
-- Structural and utility functions go in this file.

function SNFGetVersion()
	return "1.0"
end

local scount = 0

function SNFMerchant_OnUpdate()

	if not scount then scount = 1 end

	scount = scount + 1
	if mod(scount, 100) == 0 then
		SNFAuc:CheckAuctionCallback()
		scount = 0
	end
end

function SNFMerchant_OnLoad()
	SMDEBUG(1,"SNFM: Loading...");

	SlashCmdList["SNFMerchant"] = SNFMerchant_Options;
	SLASH_SNFMerchant1 = "/SNFMerchant";
	SLASH_SNFMerchant2 = "/SNFM";
	SLASH_SNFMerchant2 = "/SM";

	CHAT_PREFIX = "SNFMerchant";
	SNFMerchant_Register()
	SMDEBUG(0,"SNFM: Loaded.");
end

function SNFMerchant_Register()
	this:RegisterEvent("VARIABLES_LOADED");
	this:RegisterEvent("MERCHANT_SHOW");
--	this:RegisterEvent("CHAT_MSG_ADDON");
--	this:RegisterEvent("CHAT_MSG_RAID");
--	this:RegisterEvent("CHAT_MSG_PARTY");
--	this:RegisterEvent("CHAT_MSG_SAY");
--	this:RegisterEvent("CHAT_MSG_RAID_WARNING");
--	this:RegisterEvent("CHAT_MSG_RAID_LEADER");
--	this:RegisterEvent("CHAT_MSG_WHISPER");
--	this:RegisterEvent("GUILD_ROSTER_UPDATE");
--	this:RegisterEvent("CHAT_MSG_MONEY");
--	this:RegisterEvent("LOOT_BIND_CONFIRM");
--	this:RegisterEvent("LOOT_OPENED");
--	this:RegisterEvent("LOOT_SLOT_CLEARED");
--	this:RegisterEvent("OPEN_MASTER_LOOT_LIST");
--	this:RegisterEvent("UPDATE_MASTER_LOOT_LIST");
--	this:RegisterEvent("CANCEL_LOOT_ROLL");
	this:RegisterEvent("AUCTION_HOUSE_SHOW");
	this:RegisterEvent("AUCTION_HOUSE_CLOSED");
	this:RegisterEvent("AUCTION_ITEM_LIST_UPDATE");
	this:RegisterEvent("AUCTION_OWNED_LIST_UPDATE");
	this:RegisterEvent("AUCTION_BIDDER_LIST_UPDATE");
end

function SNFMerchant_Unregister()
	this:UnregisterEvent("VARIABLES_LOADED");
	this:UnregisterEvent("MERCHANT_SHOW");
--	this:UnregisterEvent("CHAT_MSG_ADDON");
--	this:UnregisterEvent("CHAT_MSG_RAID");
--	this:UnregisterEvent("CHAT_MSG_PARTY");
--	this:UnregisterEvent("CHAT_MSG_SAY");
--	this:UnregisterEvent("CHAT_MSG_RAID_WARNING");
---	this:UnregisterEvent("CHAT_MSG_WHISPER");
--	this:UnregisterEvent("OPEN_MASTER_LOOT_LIST");
--	this:UnregisterEvent("GUILD_ROSTER_UPDATE");
--	this:UnregisterEvent("PARTY_MEMBERS_CHANGED");
---
--	this:UnregisterEvent("PARTY_MEMBERS_CHANGED");
--	this:UnregisterEvent("RAID_ROSTER_UPDATE");
end

function SNFMerchant_OnEvent(event, ...)

	if  event == "VARIABLES_LOADED"  then
		bVarsLoaded = true;
		return
	elseif event == "AUCTION_HOUSE_SHOW" then
		SNFAuc:InterfaceOn()
		return
	elseif event == "AUCTION_HOUSE_CLOSED" then
		SNFAuc:InterfaceOff()
		return
	elseif event == "AUCTION_ITEM_LIST_UPDATE" then
		SNFAuc:UpdateList()
		return
	elseif event == "AUCTION_OWNED_LIST_UPDATE" then
		SNFAuc:UpdateOwned()
		return
	elseif event == "AUCTION_BIDDER_LIST_UPDATE" then
		SNFAuc:UpdateBids()
		return
	elseif event == "MERCHANT_SHOW" then
		SMItemSource:ScanVendor()
		return
	else
		SMDEBUG(3,"Unhandled event: "..event)
	end
end

function SMDEBUG(level, msg)
	-- not bVarsLoaded protects this against running when all functions aren't loaded
	if type(level) ~= "number" then
		DEFAULT_CHAT_FRAME:AddMessage("SNFMerchant BADLEVEL: "..(msg or "nil"))
		DEFAULT_CHAT_FRAME:AddMessage(debugstack())
		return
	end
	if (not bVarsLoaded or level <= SNFMGetDebugLevel()) then
		DEFAULT_CHAT_FRAME:AddMessage("SNFMer: "..msg)
	end
end

function SNFGetItemID(loot)
	if loot then

		itemString, name = strmatch(loot, "|c%x+|H(.+)|h(.+)|h|r")

		if itemString and name then
--			SMDEBUG(4,"Found: "..itemString..", "..name)
			local val = strmatch(itemString, "item:(%d+):.*")
			if not val and loot then
				SMDEBUG(1, "NO ITEMID FOUND FOR: "..gsub(loot, "\124", "\124\124"))
			end
			return val
		else
			SMDEBUG(1,"NO ITEMSTRING FOR: "..gsub(loot, "\124", "\124\124"))
		end
	end
	return ""
end

function SNFGetItemLevel(itemid)
	if itemid then
		local itemName, itemLink, itemRarity, itemLevel, itemMinLevel, itemType, itemSubType, itemStackCount,
		itemEquipLoc, itemTexture, itemSellPrice = GetItemInfo(itemid)
		return itemLevel;
	else
		SMDEBUG(3, "Unable to get itemlevel for "..(itemid or "nil"))
	end
	return 0
end

function SNFGetDisplayStringFromItemID(itemid)
	local _, itemLink = GetItemInfo(itemid);
	if itemLink then
		SMDEBUG(3,"ITEMID#Generated: "..itemLink)
		return itemLink
	else
		SMDEBUG(3, "ITEMD#None for "..itemid)
	end
	return "item:"..(itemid or "nil")
end

function SNFPRINT(d, name, value, depth)
	local plist = { }
	local indent = " "
	SNFPRINTHELP2(name, value, indent, plist, (depth or 99))

	for i, txt in ipairs(plist) do
		SMDEBUG(d, txt)
	end
end

function SNFPRINTHELP(name, value, indent, plist)

	if type(value) == "nil" then
		tinsert(plist, indent..(name or "nil").."=nil")
		return
	end
	if type(value) == "number" or
	   type(value) == "string" or
	   type(value) == "boolean" then
		tinsert(plist, indent..name.."="..value)
		return
	end
	if type(value) == "function" then
		tinsert(plist, indent..name.."=function")
		return
	end
	if type(value) == "thread" then
		tinsert(plist, indent..name.."=thread")
		return
	end
	if type(value) == "userdata" then
		tinsert(plist, indent..name.."=userdata")
		return
	end
	if type(value) == "table" then
		tinsert(plist, indent..name.."= {")
		for key, val in pairs(value) do
			SNFPRINTHELP(key, val, indent.."  ", plist)
		end
		tinsert(plist, indent.."}")
	end
end


function SNFPRINTHELP2(name, value, indent, plist, depth)

	if not depth or depth == 0 then return end

	if type(value) == "nil" then
		tinsert(plist, indent..(name or "nil").."=nil")
		return
	end
	if type(value) == "number" or
	   type(value) == "string" or
	   type(value) == "boolean" then
		tinsert(plist, indent..name.."="..value)
		return
	end
	if type(value) == "function" then
		tinsert(plist, indent..name.."=function")
		return
	end
	if type(value) == "thread" then
		tinsert(plist, indent..name.."=thread")
		return
	end
	if type(value) == "userdata" then
		tinsert(plist, indent..name.."=userdata")
		return
	end
	if type(value) == "table" then
		if false and #(value) < 2 then  -- shorten the display if there is only 1 value in the list
			local msg = "= {"
			local used = true
			for key, val in pairs(value) do
				if type(val) == "table" then
					tinsert(plist, indent..name.."= {")
					SNFPRINTHELP2(key, val, indent.."  ", plist, (depth or 1) -1)
					tinsert(plist, indent.."}")
					used = false
				else
					if type(value) == "boolean" then
						local vv = "true"
						if not val then vv = "false"
							msg = msg.." "..key.."="..vv..","
						else
							msg = msg.." "..key.."="..val..","
						end
					end
				end
			end
			if used then
				msg = msg.." }"
				tinsert(plist, indent..msg)
			end
			return
		else
			tinsert(plist, indent..name.."= {")
			for key, val in pairs(value) do
				SNFPRINTHELP2(key, val, indent.."  ", plist, (depth or 1) -1)
			end
			tinsert(plist, indent.."}")
		end
	end
end

 function SNFtcopy(to, from)   -- "to" must be a table (possibly empty)
   for k,v in pairs(from) do
     if(type(v)=="table") then
       to[k] = {}
       SNFtcopy(to[k], v);
     else
       to[k] = v;
     end
   end
 end

 function SNFRound(num)

   if type(num) ~= "number" then return "NaN" end

   if (num - floor(num)) >= .5 then return floor(num) + 1 end

   return floor(num)
 end

